package com.ziyun.pop.common.utils;

import io.renren.common.exception.RRException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ChineseCalendarUtils {

	private static Logger logger = LoggerFactory.getLogger(ChineseCalendarUtils.class);

	// 法律规定的放假日期
	private static List<String> lawHolidays = Arrays.asList("2018-06-30","2018-07-01","2018-07-07",
			"2018-07-08","2018-07-14","2018-07-15","2018-07-21","2018-07-22","2018-07-28",
			"2018-07-29","2018-08-04","2018-08-05","2018-08-11","2018-08-12","2018-08-18",
			"2018-08-19","2018-08-25","2018-08-26","2018-09-01","2018-09-02","2018-09-08",
			"2018-09-09","2018-09-15","2018-09-16","2018-09-22","2018-09-23","2018-09-24",
			"2018-10-01","2018-10-02","2018-10-03","2018-10-04","2018-10-05","2018-10-06",
			"2018-10-07","2018-10-13","2018-10-14","2018-10-20","2018-10-21","2018-10-27",
			"2018-10-28","2018-11-03","2018-11-04","2018-11-10","2018-11-11","2018-11-17",
			"2018-11-18","2018-11-24","2018-11-25","2018-12-01","2018-12-02","2018-12-08",
			"2018-12-09","2018-12-15","2018-12-16","2018-12-22","2018-12-23","2018-12-29",
			"2018-12-30","2019-01-05","2018-01-06","2018-01-12","2018-01-13","2018-01-19",
			"2018-01-20","2018-01-26","2018-01-27");

	/**
	 * 判断传入时间 是否是 工作日
	 */
	public static boolean isWorkDay(Date day) {
		String date = formattedDateToString(day);
		if(date == null) {
			return false;
		}

		if(lawHolidays.contains(date)) {
			return false;
		}

		return true;
	}

	/**
	 * 获取传入时间 的下一个工作日时间
	 */
	public static String getNextWorkDate(Date day) {
		String date = formattedDateToString(day);

		if(date == null) {
			return null;
		}

		//判断当前时间增加一天，是否在节假日当中
		Date nowdate = formattedDateToDate(date);
		Date addDate = nowdate;
		//是否为工作日
		boolean flag = true;
		do{
			// 时间加一天
			addDate = addDate(addDate, 1);
			String addDateStr = formattedDateToString(addDate);
			// 若日期 在 非工作日集合里，则当前日期不是 工作日
			if (lawHolidays.contains(addDateStr)) {
				flag = false;
			}else {
				flag = true;
			}
		}while(!flag);

		return formattedDateToString(addDate);
	}

	/**
	 * 获取传入时间  距离下一个工作日天数，如 2018-06-29（周五），距离下一个工作日2018-07-02天数3
	 */
	public static int getNextWorkDays(Date day) {
		String date = formattedDateToString(day);

		if(date == null) {
			return 0;
		}

		//判断当前时间增加一天，是否在节假日当中
		Date nowdate = formattedDateToDate(date);
		Date addDate = nowdate;
		//是否为工作日
		boolean flag = true;
		do{
			// 时间加一天
			addDate = addDate(addDate, 1);
			String addDateStr = formattedDateToString(addDate);
			// 若日期 在 非工作日集合里，则当前日期不是 工作日
			if (lawHolidays.contains(addDateStr)) {
				flag = false;
			}else {
				flag = true;
			}
		}while(!flag);

		return (int) ((addDate.getTime()-nowdate.getTime())/(24*60*60*1000));
	}

	/**
	 * 比较时间 date 是否 在 day 之前
	 * @param date
	 * @param time HH:mm:ss
	 * @return date 在 day 之前 返回 true，超过 time 时间 返回 false
	 * @throws RRException
	 * @throws ParseException
	 */
	public static boolean compareHourMinute(Date date,String time) throws RRException {
		String reg = "[0-9]{2}:[0-9]{2}:[0-9]{2}";//HH:mm:ss
		boolean flag = Pattern.compile(reg).matcher(time).matches();
		if(!flag) {
			throw new RRException("比较时间格式异常");
		}

		String dateStr = formattedDateToString(date);

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		Date compareDate = null;
		try {
			compareDate = formatter.parse(dateStr + " "+time);
		} catch (ParseException e) {
			throw new RRException("比较转换异常"+e.getMessage());
		}

		if(date.getTime() >= compareDate.getTime()) {
			return false;
		}
		return true;
	}

	/**
	 * 比较日期相差天数（只比较日期），如 "2018-01-01 23:00:00" 与 "2018-01-02 06:00:00" 相差 1天
	 * @param maxDate
	 * @param minDate
	 * @return
	 */
	public static int getDifferenceDays(Date maxDate, Date minDate) {
		String maxDateStr = formattedDateToString(maxDate);
		String minDateStr = formattedDateToString(minDate);

		maxDate = formattedDateToDate(maxDateStr);
		minDate = formattedDateToDate(minDateStr);

		return (int) ((maxDate.getTime()-minDate.getTime())/(24*60*60*1000));
	}

	/**
	 * 增加天数
	 * @param date
	 * @param days 整数往后推,负数往前移动
	 * @return
	 */
	@SuppressWarnings("static-access")
	public static Date addDate(Date date,int days) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(calendar.DATE,days);//把日期往后增加一天.整数往后推,负数往前移动
		date=calendar.getTime();   //这个时间就是日期往后推一天的结果
		return date;
	}

	/**
	 * 判断是否是法定假日
	 *
	 * @param calendar
	 * @return
	 * @throws Exception
	 */
	public static boolean isLawHoliday(String calendar) throws Exception {
		isMatchDateFormat(calendar);
		if (lawHolidays.contains(calendar)) {
			return true;
		}
		return false;
	}


	/**
	 * 格式化时间 转字符串
	 * @param day
	 * @return yyyy-MM-dd
	 */
	private static String formattedDateToString(Date day) {
		if(day == null) {
			return null;
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String formatStr =formatter.format(day);
		logger.info("格式化时间--"+formatStr);
		return formatStr;
	}

	/**
	 * 格式化字符串 转 时间
	 * @param date "yyyy-MM-dd"
	 * @return
	 */
	private static Date formattedDateToDate(String date) {
		if(date == null) {
			return null;
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		Date day = null;
		try {
			day = formatter.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		logger.info("格式化时间--"+day.toString());
		return day;
	}


	/**
	 * 判断是否是周末
	 *
	 * @param calendar
	 * @return
	 * @throws ParseException
	 */
	public static boolean isWeekends(String calendar) throws Exception {
		isMatchDateFormat(calendar);
		// 先将字符串类型的日期转换为Calendar类型
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = sdf.parse(calendar);
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		if (ca.get(Calendar.DAY_OF_WEEK) == 1
				|| ca.get(Calendar.DAY_OF_WEEK) == 7) {
			return true;
		}
		return false;
	}

	/**
	 * 使用正则表达式匹配日期格式
	 *
	 * @throws Exception
	 */
	private static void isMatchDateFormat(String calendar) throws Exception {
		Pattern pattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
		Matcher matcher = pattern.matcher(calendar);
		boolean flag = matcher.matches();
		if (!flag) {
			throw new Exception("输入日期格式不正确，应该为2017-12-19");
		}
	}


}
